<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.9.1"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>FLAC: Porting from FLAC 1.1.2 to 1.1.3</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectalign" style="padding-left: 0.5em;">
   <div id="projectname">FLAC
   &#160;<span id="projectnumber">1.4.3</span>
   </div>
   <div id="projectbrief">Free Lossless Audio Codec</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.1 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
  initMenu('',false,false,'search.php','Search');
});
/* @license-end */</script>
<div id="main-nav"></div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">Porting from FLAC 1.1.2 to 1.1.3<div class="ingroups"><a class="el" href="group__porting.html">Porting Guide for New Versions</a></div></div>  </div>
</div><!--header-->
<div class="contents">
<p>This module describes porting from FLAC 1.1.2 to FLAC 1.1.3. </p>
<p>The main change between the APIs in 1.1.2 and 1.1.3 is that they have been simplified. First, libOggFLAC has been merged into libFLAC and libOggFLAC++ has been merged into libFLAC++. Second, both the three decoding layers and three encoding layers have been merged into a single stream decoder and stream encoder. That is, the functionality of FLAC__SeekableStreamDecoder and FLAC__FileDecoder has been merged into <a class="el" href="structFLAC____StreamDecoder.html">FLAC__StreamDecoder</a>, and FLAC__SeekableStreamEncoder and FLAC__FileEncoder into <a class="el" href="structFLAC____StreamEncoder.html">FLAC__StreamEncoder</a>. Only the <a class="el" href="structFLAC____StreamDecoder.html">FLAC__StreamDecoder</a> and <a class="el" href="structFLAC____StreamEncoder.html">FLAC__StreamEncoder</a> remain. What this means is there is now a single API that can be used to encode or decode streams to/from native FLAC or Ogg FLAC and the single API can work on both seekable and non-seekable streams.</p>
<p>Instead of creating an encoder or decoder of a certain layer, now the client will always create a <a class="el" href="structFLAC____StreamEncoder.html">FLAC__StreamEncoder</a> or <a class="el" href="structFLAC____StreamDecoder.html">FLAC__StreamDecoder</a>. The old layers are now differentiated by the initialization function. For example, for the decoder, FLAC__stream_decoder_init() has been replaced by <a class="el" href="group__flac__stream__decoder.html#ga150d381abc5249168e439bc076544b29">FLAC__stream_decoder_init_stream()</a>. This init function takes callbacks for the I/O, and the seeking callbacks are optional. This allows the client to use the same object for seekable and non-seekable streams. For decoding a FLAC file directly, the client can use <a class="el" href="group__flac__stream__decoder.html#ga4021ead5cff29fd589c915756f902f1a">FLAC__stream_decoder_init_file()</a> and pass just a filename and fewer callbacks; most of the other callbacks are supplied internally. For situations where fopen()ing by filename is not possible (e.g. Unicode filenames on Windows) the client can instead open the file itself and supply the FILE* to <a class="el" href="group__flac__stream__decoder.html#ga80aa83631460a53263c84e654586dff0">FLAC__stream_decoder_init_FILE()</a>. The init functions now returns a FLAC__StreamDecoderInitStatus instead of FLAC__StreamDecoderState. Since the callbacks and client data are now passed to the init function, the FLAC__stream_decoder_set_*_callback() functions and FLAC__stream_decoder_set_client_data() are no longer needed. The rest of the calls to the decoder are the same as before.</p>
<p>There are counterpart init functions for Ogg FLAC, e.g. <a class="el" href="group__flac__stream__decoder.html#ga1b043adeb805c779c1e97cb68959d1ab">FLAC__stream_decoder_init_ogg_stream()</a>. All the rest of the calls and callbacks are the same as for native FLAC.</p>
<p>As an example, in FLAC 1.1.2 a seekable stream decoder would have been set up like so:</p>
<div class="fragment"><div class="line">FLAC__SeekableStreamDecoder *decoder = FLAC__seekable_stream_decoder_new();</div>
<div class="line"><span class="keywordflow">if</span>(decoder == NULL) do_something;</div>
<div class="line">FLAC__seekable_stream_decoder_set_md5_checking(decoder, <span class="keyword">true</span>);</div>
<div class="line">[... other settings ...]</div>
<div class="line">FLAC__seekable_stream_decoder_set_read_callback(decoder, my_read_callback);</div>
<div class="line">FLAC__seekable_stream_decoder_set_seek_callback(decoder, my_seek_callback);</div>
<div class="line">FLAC__seekable_stream_decoder_set_tell_callback(decoder, my_tell_callback);</div>
<div class="line">FLAC__seekable_stream_decoder_set_length_callback(decoder, my_length_callback);</div>
<div class="line">FLAC__seekable_stream_decoder_set_eof_callback(decoder, my_eof_callback);</div>
<div class="line">FLAC__seekable_stream_decoder_set_write_callback(decoder, my_write_callback);</div>
<div class="line">FLAC__seekable_stream_decoder_set_metadata_callback(decoder, my_metadata_callback);</div>
<div class="line">FLAC__seekable_stream_decoder_set_error_callback(decoder, my_error_callback);</div>
<div class="line">FLAC__seekable_stream_decoder_set_client_data(decoder, my_client_data);</div>
<div class="line"><span class="keywordflow">if</span>(FLAC__seekable_stream_decoder_init(decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) do_something;</div>
</div><!-- fragment --><p>In FLAC 1.1.3 it is like this:</p>
<div class="fragment"><div class="line"><a class="code" href="structFLAC____StreamDecoder.html">FLAC__StreamDecoder</a> *decoder = <a class="code" href="group__flac__stream__decoder.html#ga529c3c1e46417570767fb8e4c76f5477">FLAC__stream_decoder_new</a>();</div>
<div class="line"><span class="keywordflow">if</span>(decoder == NULL) do_something;</div>
<div class="line"><a class="code" href="group__flac__stream__decoder.html#ga8f402243eed54f400ddd2f296ff54497">FLAC__stream_decoder_set_md5_checking</a>(decoder, <span class="keyword">true</span>);</div>
<div class="line">[... other settings ...]</div>
<div class="line"><span class="keywordflow">if</span>(<a class="code" href="group__flac__stream__decoder.html#ga150d381abc5249168e439bc076544b29">FLAC__stream_decoder_init_stream</a>(</div>
<div class="line">  decoder,</div>
<div class="line">  my_read_callback,</div>
<div class="line">  my_seek_callback,      <span class="comment">// or NULL</span></div>
<div class="line">  my_tell_callback,      <span class="comment">// or NULL</span></div>
<div class="line">  my_length_callback,    <span class="comment">// or NULL</span></div>
<div class="line">  my_eof_callback,       <span class="comment">// or NULL</span></div>
<div class="line">  my_write_callback,</div>
<div class="line">  my_metadata_callback,  <span class="comment">// or NULL</span></div>
<div class="line">  my_error_callback,</div>
<div class="line">  my_client_data</div>
<div class="line">) != <a class="code" href="group__flac__stream__decoder.html#ggaaed54a24ac6310d29c5cafba79759c44ac94c7e9396f30642f34805e5d626e011">FLAC__STREAM_DECODER_INIT_STATUS_OK</a>) do_something;</div>
<div class="ttc" id="agroup__flac__stream__decoder_html_ga150d381abc5249168e439bc076544b29"><div class="ttname"><a href="group__flac__stream__decoder.html#ga150d381abc5249168e439bc076544b29">FLAC__stream_decoder_init_stream</a></div><div class="ttdeci">FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderReadCallback read_callback, FLAC__StreamDecoderSeekCallback seek_callback, FLAC__StreamDecoderTellCallback tell_callback, FLAC__StreamDecoderLengthCallback length_callback, FLAC__StreamDecoderEofCallback eof_callback, FLAC__StreamDecoderWriteCallback write_callback, FLAC__StreamDecoderMetadataCallback metadata_callback, FLAC__StreamDecoderErrorCallback error_callback, void *client_data)</div></div>
<div class="ttc" id="agroup__flac__stream__decoder_html_ga529c3c1e46417570767fb8e4c76f5477"><div class="ttname"><a href="group__flac__stream__decoder.html#ga529c3c1e46417570767fb8e4c76f5477">FLAC__stream_decoder_new</a></div><div class="ttdeci">FLAC__StreamDecoder * FLAC__stream_decoder_new(void)</div></div>
<div class="ttc" id="agroup__flac__stream__decoder_html_ga8f402243eed54f400ddd2f296ff54497"><div class="ttname"><a href="group__flac__stream__decoder.html#ga8f402243eed54f400ddd2f296ff54497">FLAC__stream_decoder_set_md5_checking</a></div><div class="ttdeci">FLAC__bool FLAC__stream_decoder_set_md5_checking(FLAC__StreamDecoder *decoder, FLAC__bool value)</div></div>
<div class="ttc" id="agroup__flac__stream__decoder_html_ggaaed54a24ac6310d29c5cafba79759c44ac94c7e9396f30642f34805e5d626e011"><div class="ttname"><a href="group__flac__stream__decoder.html#ggaaed54a24ac6310d29c5cafba79759c44ac94c7e9396f30642f34805e5d626e011">FLAC__STREAM_DECODER_INIT_STATUS_OK</a></div><div class="ttdeci">@ FLAC__STREAM_DECODER_INIT_STATUS_OK</div><div class="ttdef"><b>Definition:</b> stream_decoder.h:258</div></div>
<div class="ttc" id="astructFLAC____StreamDecoder_html"><div class="ttname"><a href="structFLAC____StreamDecoder.html">FLAC__StreamDecoder</a></div><div class="ttdef"><b>Definition:</b> stream_decoder.h:470</div></div>
</div><!-- fragment --><p>or you could do;</p>
<div class="fragment"><div class="line">[...]</div>
<div class="line">FILE *file = fopen(<span class="stringliteral">&quot;somefile.flac&quot;</span>,<span class="stringliteral">&quot;rb&quot;</span>);</div>
<div class="line"><span class="keywordflow">if</span>(file == NULL) do_somthing;</div>
<div class="line"><span class="keywordflow">if</span>(<a class="code" href="group__flac__stream__decoder.html#ga80aa83631460a53263c84e654586dff0">FLAC__stream_decoder_init_FILE</a>(</div>
<div class="line">  decoder,</div>
<div class="line">  file,</div>
<div class="line">  my_write_callback,</div>
<div class="line">  my_metadata_callback,  <span class="comment">// or NULL</span></div>
<div class="line">  my_error_callback,</div>
<div class="line">  my_client_data</div>
<div class="line">) != <a class="code" href="group__flac__stream__decoder.html#ggaaed54a24ac6310d29c5cafba79759c44ac94c7e9396f30642f34805e5d626e011">FLAC__STREAM_DECODER_INIT_STATUS_OK</a>) do_something;</div>
<div class="ttc" id="agroup__flac__stream__decoder_html_ga80aa83631460a53263c84e654586dff0"><div class="ttname"><a href="group__flac__stream__decoder.html#ga80aa83631460a53263c84e654586dff0">FLAC__stream_decoder_init_FILE</a></div><div class="ttdeci">FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_FILE(FLAC__StreamDecoder *decoder, FILE *file, FLAC__StreamDecoderWriteCallback write_callback, FLAC__StreamDecoderMetadataCallback metadata_callback, FLAC__StreamDecoderErrorCallback error_callback, void *client_data)</div></div>
</div><!-- fragment --><p>or just:</p>
<div class="fragment"><div class="line">[...]</div>
<div class="line"><span class="keywordflow">if</span>(<a class="code" href="group__flac__stream__decoder.html#ga4021ead5cff29fd589c915756f902f1a">FLAC__stream_decoder_init_file</a>(</div>
<div class="line">  decoder,</div>
<div class="line">  <span class="stringliteral">&quot;somefile.flac&quot;</span>,</div>
<div class="line">  my_write_callback,</div>
<div class="line">  my_metadata_callback,  <span class="comment">// or NULL</span></div>
<div class="line">  my_error_callback,</div>
<div class="line">  my_client_data</div>
<div class="line">) != <a class="code" href="group__flac__stream__decoder.html#ggaaed54a24ac6310d29c5cafba79759c44ac94c7e9396f30642f34805e5d626e011">FLAC__STREAM_DECODER_INIT_STATUS_OK</a>) do_something;</div>
<div class="ttc" id="agroup__flac__stream__decoder_html_ga4021ead5cff29fd589c915756f902f1a"><div class="ttname"><a href="group__flac__stream__decoder.html#ga4021ead5cff29fd589c915756f902f1a">FLAC__stream_decoder_init_file</a></div><div class="ttdeci">FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file(FLAC__StreamDecoder *decoder, const char *filename, FLAC__StreamDecoderWriteCallback write_callback, FLAC__StreamDecoderMetadataCallback metadata_callback, FLAC__StreamDecoderErrorCallback error_callback, void *client_data)</div></div>
</div><!-- fragment --><p>Another small change to the decoder is in how it handles unparseable streams. Before, when the decoder found an unparseable stream (reserved for when the decoder encounters a stream from a future encoder that it can't parse), it changed the state to <code>FLAC__STREAM_DECODER_UNPARSEABLE_STREAM</code>. Now the decoder instead drops sync and calls the error callback with a new error code <code>FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM</code>. This is more robust. If your error callback does not discriminate on the the error state, your code does not need to be changed.</p>
<p>The encoder now has a new setting: <a class="el" href="group__flac__stream__encoder.html#ga6598f09ac782a1f2a5743ddf247c81c8">FLAC__stream_encoder_set_apodization()</a>. This is for setting the method used to window the data before LPC analysis. You only need to add a call to this function if the default is not suitable. There are also two new convenience functions that may be useful: <a class="el" href="group__flac__metadata__object.html#gaff2f825950b3e4dda4c8ddbf8e2f7ecd">FLAC__metadata_object_cuesheet_calculate_cddb_id()</a> and <a class="el" href="group__flac__metadata__level0.html#ga0f47949dca514506718276205a4fae0b">FLAC__metadata_get_cuesheet()</a>.</p>
<p>The <em>bytes</em> parameter to FLAC__StreamDecoderReadCallback, FLAC__StreamEncoderReadCallback, and FLAC__StreamEncoderWriteCallback is now <code>size_t</code> instead of <code>uint32_t</code>. </p>
</div><!-- contents -->

<hr size="1"/>
Copyright (c) 2000-2009  Josh Coalson
Copyright (c) 2011-2023  Xiph.Org Foundation
<!-- Copyright (c) 2000-2009  Josh Coalson -->
<!-- Copyright (c) 2011-2023  Xiph.Org Foundation -->
<!-- Permission is granted to copy, distribute and/or modify this document -->
<!-- under the terms of the GNU Free Documentation License, Version 1.1 -->
<!-- or any later version published by the Free Software Foundation; -->
<!-- with no invariant sections. -->
<!-- A copy of the license can be found at http://www.gnu.org/copyleft/fdl.html -->
</body>
</html>
